"""
目前支持的提取接口返回模式，value必须从root($)开始取值：
1、"return_{key}:$.data.id/$.data.content[1].id"  自定义key
2、"return_$.data.name/return_$.data.content[1].id":$.data.id/$.data.content[1].id"  从返回中提取value作为key
3、"return_$.data.content[*].name":"id"  提取返回值list(content)所有中每个object的{name:id}
4、"return_$.data.contents[*list].id":["name","ct"]  返回举例{"123":{"name":"dd","ct":"2022-03-04"}}
5、return_values : $.data.content[*].[id,name] => {"values":[{"id1":value,"name1":value},{"id2":value,"name2":value}]}
"""

import requests
from base.logcontrol import logger
from config import CONTENT_TYPE
from base.request_tools import exec_resp_new


class RequestNew(object):

    def __init__(self, host: str = "", cookie=None):
        self.host = host
        self.cookie = cookie

    def __repr__(self):
        return f"{type(self).__name__} OBJ"

    def __integrate_req(self, method, url, data, content_type, **kwargs):
        # 整合请求参数
        headers = {
            "Content-Type": CONTENT_TYPE[content_type.upper()],
            "charset": "UTF-8"
        }
        req_json, req_params, req_data = None, None, None
        req_cookies, cookies = None, None
        if str(method).upper() == "POST":
            method = "POST"
            if content_type.upper() == "FORM":
                req_data = data
            else:
                req_json = data
        else:
            method = "GET"
            req_params = data

        # 获取cookie
        if self.cookie:
            cookies = self.cookie
        elif "cookies" in data:
            cookies = data.pop("cookies")
        elif "cookies" in kwargs:
            cookies = kwargs["cookies"]

        if cookies:
            if isinstance(cookies, dict):
                req_cookies = cookies
            elif isinstance(cookies, str):
                headers.update({"Cookie": cookies.strip(" ")})
            else:
                logger.warning(f"cookies类型不是字典或字符串cookies：{cookies}")

        return {
            "method": method,
            "url": self.host + url,
            "json": req_json,
            "data": req_data,
            "params": req_params,
            "cookies": req_cookies,
            "headers": headers,
            "timeout": 20.0
        }

    def request_auto(self,
                     method: str,
                     url: str,
                     data: dict,
                     content_type: str = "JSON",
                     **kwargs):
        try:
            resp = requests.request(**self.__integrate_req(method, url, data, content_type, **kwargs))
        except Exception as e:
            logger.error(f"\n\t接口请求异常\n"
                         f"\t异常：{e}\n")
            raise RuntimeError(f"{url}请求异常")

        if resp.status_code == 200:
            # 处理请求参数
            response, return_vars = exec_resp_new(resp, kwargs)

            logger.debug(f"\n\t********RequestAuto********\n"
                         f"\t请求：{resp.request.__dict__}\n"
                         f"\t返回：{response}\n"
                         f"\t提取参数：{return_vars}\n")
            return response, return_vars

        msg = f"{resp.request.__dict__}请求异常"
        logger.error(f"\n\t请求发生异常\n"
                     f"\t请求：{resp.request.__dict__}\n"
                     f"\t返回：{resp}\n")
        raise RuntimeError(msg)
